package com.ssy.lingxi.purchase.serviceimpl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.logistics.api.dto.response.ReceiverAddressResponse;
import com.ssy.lingxi.logistics.api.feign.ReceiverAddressControllerFeign;
import com.ssy.lingxi.purchase.api.common.OrderConstant;
import com.ssy.lingxi.purchase.api.dto.request.CommonIdRequest;
import com.ssy.lingxi.purchase.entity.*;
import com.ssy.lingxi.purchase.model.bo.FileUploadBO;
import com.ssy.lingxi.purchase.model.convert.JpaJsonToFileUploadVOConverter;
import com.ssy.lingxi.purchase.model.enums.*;
import com.ssy.lingxi.purchase.model.request.*;
import com.ssy.lingxi.purchase.model.response.*;
import com.ssy.lingxi.purchase.model.vo.FileUploadVO;
import com.ssy.lingxi.purchase.repository.PurchaseRequisitionRepository;
import com.ssy.lingxi.purchase.service.ICommonService;
import com.ssy.lingxi.purchase.service.IPurchaseRequisitionService;
import com.ssy.lingxi.purchase.utils.DateUtil;
import com.ssy.lingxi.purchase.utils.NumberUtil;
import com.ssy.lingxi.workflow.api.feign.ProcessMemberRoleControllerFeign;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import javax.persistence.Column;
import javax.persistence.Convert;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @menu 采购能力-采购请购单相关实现
 * @author wyx
 * @version 2.0.0
 * @date 2021-10-27
 */
@Service
public class PurchaseRequisitionServiceImpl implements IPurchaseRequisitionService {
    @Resource
    private PurchaseRequisitionRepository purchaseRequisitionRepository;
    @Resource
    private ICommonService commonService;
    @Resource
    private JPAQueryFactory jpaQueryFactory;

    @Resource
    private ReceiverAddressControllerFeign receiverAddressControllerFeign;


    /**
     * 分页查询请购单
     * @param loginUser 登录用户信息
     * @param req       接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<RequisitionPageRes>> getPage(UserLoginCacheDTO loginUser, RequisitionPageReq req) {
        //构造查询条件
        return commonService.getBaseRequisitionPage(loginUser, req, null, null);
    }

    /**
     * 待新增请购单-分页查询
     * @param loginUser 登录用户信息
     * @param req       接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<RequisitionPageRes>> getCreatePage(UserLoginCacheDTO loginUser, RequisitionPageReq req) {
        //构造查询条件，内部状态为 待提交审核、一级审核不通过、二级审核不通过
        return commonService.getBaseRequisitionPage(loginUser, req,
                Arrays.asList(RequisitionInnerStatusEnum.BUYER_TO_SUBMIT_VALIDATE.getCode(), RequisitionInnerStatusEnum.BUYER_GRADE_ONE_NOT_PASSED.getCode(), RequisitionInnerStatusEnum.BUYER_GRADE_TWO_NOT_PASSED.getCode()), null);
    }

    /**
     * 待审核请购单(一级)-分页查询
     * @param loginUser 登录用户信息
     * @param req       接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<RequisitionPageRes>> getFirstAuditPage(UserLoginCacheDTO loginUser, RequisitionPageReq req) {
        //构造查询条件，内部状态为 待一级审核
        return commonService.getBaseRequisitionPage(loginUser, req, Collections.singletonList(RequisitionInnerStatusEnum.BUYER_VALIDATE_GRADE_ONE.getCode()), null);
    }

    /**
     * 待审核请购单(二级)-分页查询
     * @param loginUser 登录用户信息
     * @param req       接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<RequisitionPageRes>> getTwoAuditPage(UserLoginCacheDTO loginUser, RequisitionPageReq req) {
        //构造查询条件，内部状态为 待二级审核
        return commonService.getBaseRequisitionPage(loginUser, req, Collections.singletonList(RequisitionInnerStatusEnum.BUYER_VALIDATE_GRADE_TWO.getCode()), null);
    }

    /**
     * 待提交请购单-分页查询
     * @param loginUser 登录用户信息
     * @param req       接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<RequisitionPageRes>> getSubmitPage(UserLoginCacheDTO loginUser, RequisitionPageReq req) {
        //构造查询条件，内部状态为 待提交
        return commonService.getBaseRequisitionPage(loginUser, req, Collections.singletonList(RequisitionInnerStatusEnum.BUYER_TO_SUBMIT.getCode()), null);
    }

    /**
     * 创建采购请购单
     * @param loginUser 登录用户信息
     * @param req       接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> create(UserLoginCacheDTO loginUser, RequisitionReq req) {
        //规则校验：
        // a. 会员不能购买自己的商品
        if (loginUser.getMemberId().equals(req.getVendorMemberId())) {
            return Wrapper.fail(ResponseCode.ORDER_CAN_NOT_PURCHASE_OWN_PRODUCTS);
        }

        //创建请购单
        PurchaseRequisition requisition = new PurchaseRequisition();
        requisition.setRequisitionNo(NumberUtil.randomUniqueNumber());
        requisition.setCreateTime(LocalDateTime.now());
        requisition.setDeliverTime(DateUtil.convertDeliverTime(req.getDeliverTime()));
        requisition.setBuyerMemberId(loginUser.getMemberId());
        requisition.setBuyerRoleId(loginUser.getMemberRoleId());
        requisition.setBuyerMemberName(loginUser.getCompany());
        requisition.setVendorMemberId(req.getVendorMemberId());
        requisition.setVendorRoleId(req.getVendorRoleId());
        requisition.setVendorMemberName(req.getVendorMemberName());
        requisition.setDepartment(req.getDepartment());
        requisition.setDepartmentId(req.getDepartmentId());
        requisition.setPurpose(req.getPurpose());
        requisition.setDigest(req.getDigest());
        requisition.setCreator(loginUser.getUserName());
        requisition.setRequisitionerId(req.getRequisitionerId());
        requisition.setRequisitioner(req.getRequisitioner());
        requisition.setAttachments(req.getAttachments());
        requisition.setAdvanceDeliveryDate(req.getAdvanceDeliveryDate());
        requisition.setDeliveryMethod(req.getDeliveryMethod());
        requisition.setDeliveryType(req.getDeliveryType());
        requisition.setDeliveryAddress(req.getDeliveryAddress());
        requisition.setDeliveryAddressId(req.getDeliveryAddressId());
        // 保存以生成订单的Id
        purchaseRequisitionRepository.save(requisition);

        //检查商品信息，获得总金额
        Wrapper<PurchaseProductCheckRes> productCheckResult = commonService.checkRequisitionProduct(requisition, req.getProducts(), true);
        if (productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
        }
        requisition.setQuantity(productCheckResult.getData().getQuantity());
        requisition.setTransferQuantity(BigDecimal.ZERO);
        requisition.setProductAmount(productCheckResult.getData().getProductAmount());

        //工作流任务
        PurchaseProcessTask processTask = new PurchaseProcessTask();
        processTask.setProcessKey(PurchaseConstants.PURCHASE_REQUISITION_INNER_VERIFY);
        processTask.setTaskId("");
        requisition.setTask(processTask);

        //执行审核工作流（注意这里是直接启动）
        Wrapper<PurchaseProcessTaskRes> taskResult = commonService.startPurchaseProcess(requisition);
        if (taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }
        //保存
        purchaseRequisitionRepository.save(requisition);
        //内部流转记录
        commonService.savePurchaseInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), requisition.getId(), RequisitionOperationEnum.CREATE.getName(), RequisitionInnerStatusEnum.getNameByCode(requisition.getBuyerInnerStatus()), "");
        return Wrapper.success();
    }

    /**
     * 修改请购单
     * @param loginUser 登录用户信息
     * @param req       接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> update(UserLoginCacheDTO loginUser, RequisitionUpdateReq req) {
        PurchaseRequisition requisition = purchaseRequisitionRepository.findById(req.getRequisitionId()).orElse(null);
        if (requisition == null) {
            return Wrapper.fail(ResponseCode.EXCEL_UPLOAD_ERROR_NULL);
        }
        requisition.setCreator(loginUser.getUserName());
        requisition.setCreateTime(LocalDateTime.now());
        requisition.setDeliverTime(DateUtil.convertDeliverTime(req.getDeliverTime()));
        requisition.setVendorMemberId(req.getVendorMemberId());
        requisition.setVendorRoleId(req.getVendorRoleId());
        requisition.setVendorMemberName(req.getVendorMemberName());
        requisition.setDepartmentId(req.getDepartmentId());
        requisition.setDepartment(req.getDepartment());
        requisition.setPurpose(req.getPurpose());
        requisition.setDigest(req.getDigest());
        requisition.setBuyerInnerStatus(RequisitionInnerStatusEnum.BUYER_TO_SUBMIT_VALIDATE.getCode());
        requisition.setRequisitionerId(req.getRequisitionerId());
        requisition.setRequisitioner(req.getRequisitioner());
        requisition.setAttachments(req.getAttachments());
        requisition.setAdvanceDeliveryDate(req.getAdvanceDeliveryDate());
        requisition.setDeliveryMethod(req.getDeliveryMethod());
        requisition.setDeliveryType(req.getDeliveryType());
        requisition.setDeliveryAddress(req.getDeliveryAddress());
        requisition.setDeliveryAddressId(req.getDeliveryAddressId());

        //保存以生成订单的Id
        purchaseRequisitionRepository.save(requisition);

        //检查商品信息，获得总金额
        Wrapper<PurchaseProductCheckRes> productCheckResult = commonService.checkRequisitionProduct(requisition, req.getProducts(), false);
        if (productCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(productCheckResult.getCode(), productCheckResult.getMessage());
        }
        requisition.setProductAmount(productCheckResult.getData().getProductAmount());
        requisition.setQuantity(productCheckResult.getData().getQuantity());
        requisition.setTransferQuantity(BigDecimal.ZERO);

        //保存修改的请购单
        purchaseRequisitionRepository.save(requisition);
        //内部流转记录
        commonService.savePurchaseInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), requisition.getId(), RequisitionOperationEnum.MODIFY.getName(), RequisitionInnerStatusEnum.getNameByCode(requisition.getBuyerInnerStatus()), "");
        return Wrapper.success();
    }

    /**
     * 采购请购单详情
     * @param loginUser 登录用户信息
     * @param req       接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<RequisitionDetailRes> getDetail(UserLoginCacheDTO loginUser, CommonIdRequest req) {
        PurchaseRequisition requisition = purchaseRequisitionRepository.findById(req.getId()).orElse(null);
        if (requisition == null) {
            return Wrapper.fail(ResponseCode.EXCEL_UPLOAD_ERROR_NULL);
        }
        if (!requisition.getBuyerMemberId().equals(loginUser.getMemberId()) || !requisition.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_WRONG_ROLE);
        }

        //调用工作流服务接口，查询流程步骤定义
        Wrapper<ProcessStepsRes> stepResult = commonService.findRequisitionProcessSteps(requisition.getTask().getProcessKey(), requisition.getTask().getTaskId(), requisition.getVendorMemberId());
        if (stepResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(stepResult.getCode(), stepResult.getMessage());
        }

        RequisitionDetailRes detailRes = new RequisitionDetailRes();
        //基本信息
        detailRes.setInnerSteps(stepResult.getData().getInnerSteps());
        detailRes.setCurrentInnerStep(stepResult.getData().getCurrentInnerStep());
        detailRes.setRequisitionId(requisition.getId());
        detailRes.setRequisitionNo(requisition.getRequisitionNo());
        detailRes.setInnerStatus(requisition.getBuyerInnerStatus());
        detailRes.setInnerStatusName(RequisitionInnerStatusEnum.getNameByCode(requisition.getBuyerInnerStatus()));
        detailRes.setDigest(requisition.getDigest());
        detailRes.setDeliverTime(requisition.getDeliverTime() == null ? "" : requisition.getDeliverTime().format(PurchaseConstants.DEFAULT_DATE_FORMATTER));
        detailRes.setDepartmentId(requisition.getDepartmentId());
        detailRes.setDepartment(requisition.getDepartment());
        detailRes.setPurpose(requisition.getPurpose());
        detailRes.setVendorMemberId(requisition.getVendorMemberId());
        detailRes.setVendorRoleId(requisition.getVendorRoleId());
        detailRes.setVendorMemberName(requisition.getVendorMemberName());
        detailRes.setCreator(requisition.getCreator());
        detailRes.setCreateTime(requisition.getCreateTime().format(PurchaseConstants.DEFAULT_TIME_FORMATTER));
        BeanUtils.copyProperties(requisition, detailRes);
        detailRes.setDeliveryMethodName(DeliveryMethodEnum.getCodeMsg(NumberUtil.isNullOrZero(requisition.getDeliveryMethod()) ? 0 : requisition.getDeliveryMethod()));
        detailRes.setDeliveryTypeName(DeliveryTypeEnum.getCodeMsg(NumberUtil.isNullOrZero(requisition.getDeliveryType()) ? 0 : requisition.getDeliveryType()));
        detailRes.setReceiverAddressResponse(requisition.getDeliveryAddressId() != null ? receiverAddressControllerFeign.getReceiverAddress(requisition.getDeliveryAddressId()).getData() : null);
        //订单商品汇总信息
        PurchaseProductRes productRes = commonService.purchaseProducts(requisition);
        detailRes.setProduct(productRes.getProductVO());
        //内部流转记录
        detailRes.setInnerHistories(commonService.listBuyerOrderInnerHistories(requisition.getBuyerMemberId(), requisition.getBuyerRoleId(), requisition.getId()));
        return Wrapper.success(detailRes);
    }

    /**
     * 删除请购单
     * @param req 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<Void> delete(UserLoginCacheDTO loginUser, CommonIdRequest req) {
        purchaseRequisitionRepository.deleteById(req.getId());
        return Wrapper.success();
    }

    /**
     * 中止采购请购单
     * @param loginUser 登录用户信息
     * @param req       接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<RequisitionDetailRes> pause(UserLoginCacheDTO loginUser, RequisitionInnerStatusReq req) {
        PurchaseRequisition requisition = purchaseRequisitionRepository.findById(req.getId()).orElse(null);
        if (requisition == null) {
            return Wrapper.fail(ResponseCode.EXCEL_UPLOAD_ERROR_NULL);
        }
        requisition.setBuyerInnerStatus(RequisitionInnerStatusEnum.TERMINATED.getCode());
        purchaseRequisitionRepository.save(requisition);

        //内部流转记录
        commonService.savePurchaseInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), req.getId(), RequisitionOperationEnum.TERMINATE.getName(), RequisitionInnerStatusEnum.getNameByCode(requisition.getBuyerInnerStatus()), req.getReason());
        return Wrapper.success();
    }

    /**
     * 取消采购请购单
     * @param loginUser 登录用户信息
     * @param req       接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<RequisitionDetailRes> cancel(UserLoginCacheDTO loginUser, RequisitionInnerStatusReq req) {
        PurchaseRequisition requisition = purchaseRequisitionRepository.findById(req.getId()).orElse(null);
        if (requisition == null) {
            return Wrapper.fail(ResponseCode.EXCEL_UPLOAD_ERROR_NULL);
        }
        requisition.setBuyerInnerStatus(RequisitionInnerStatusEnum.CANCELLED.getCode());
        purchaseRequisitionRepository.save(requisition);

        //内部流转记录
        commonService.savePurchaseInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), req.getId(), RequisitionOperationEnum.CANCEL.getName(), RequisitionInnerStatusEnum.getNameByCode(requisition.getBuyerInnerStatus()), req.getReason());
        return Wrapper.success();
    }

    /**
     * 待新增请购单-提交审核
     * @param loginUser 登录用户信息
     * @param req       接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> submitAudit(UserLoginCacheDTO loginUser, CommonIdRequest req) {
        PurchaseRequisition requisition = purchaseRequisitionRepository.findById(req.getId()).orElse(null);
        if (requisition == null) {
            return Wrapper.fail(ResponseCode.EXCEL_UPLOAD_ERROR_NULL);
        }
        //执行请购单下个流程
        Wrapper<PurchaseProcessTaskRes> taskResult = commonService.executeRequisitionProcess(requisition, PurchaseConstants.DIRECT_EXEC_TASK);
        if (taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }
        //保存修改的请购单
        purchaseRequisitionRepository.save(requisition);
        //内部流转记录
        commonService.savePurchaseInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), req.getId(), RequisitionOperationEnum.SUBMIT_VALIDATE.getName(), RequisitionInnerStatusEnum.getNameByCode(requisition.getBuyerInnerStatus()), "");
        return Wrapper.success();
    }

    /**
     * 待审核请购单一级-审核
     * @param req 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> firstAudit(UserLoginCacheDTO loginUser, RequisitionAuditReq req) {
        PurchaseRequisition requisition = purchaseRequisitionRepository.findById(req.getId()).orElse(null);
        if (requisition == null) {
            return Wrapper.fail(ResponseCode.EXCEL_UPLOAD_ERROR_NULL);
        }
        //执行请购单下个流程
        Wrapper<PurchaseProcessTaskRes> taskResult = commonService.executeRequisitionProcess(requisition, req.getAgree());
        if (taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }
        //保存修改的请购单
        purchaseRequisitionRepository.save(requisition);
        //内部流转记录
        commonService.savePurchaseInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), req.getId(), RequisitionOperationEnum.VALIDATE_GRADE_ONE.getName(), RequisitionInnerStatusEnum.getNameByCode(requisition.getBuyerInnerStatus()), "");
        return Wrapper.success();
    }

    /**
     * 待审核请购单二级-审核
     * @param req 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> twoAudit(UserLoginCacheDTO loginUser, RequisitionAuditReq req) {
        PurchaseRequisition requisition = purchaseRequisitionRepository.findById(req.getId()).orElse(null);
        if (requisition == null) {
            return Wrapper.fail(ResponseCode.EXCEL_UPLOAD_ERROR_NULL);
        }
        //执行请购单下个流程
        Wrapper<PurchaseProcessTaskRes> taskResult = commonService.executeRequisitionProcess(requisition, req.getAgree());
        if (taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }
        //保存修改的请购单
        purchaseRequisitionRepository.save(requisition);
        //内部流转记录
        commonService.savePurchaseInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), req.getId(), RequisitionOperationEnum.VALIDATE_GRADE_TWO.getName(), RequisitionInnerStatusEnum.getNameByCode(requisition.getBuyerInnerStatus()), "");
        return Wrapper.success();
    }

    /**
     * 待提交请购单-提交
     * @param req 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> submit(UserLoginCacheDTO loginUser, CommonIdRequest req) {
        PurchaseRequisition requisition = purchaseRequisitionRepository.findById(req.getId()).orElse(null);
        if (requisition == null) {
            return Wrapper.fail(ResponseCode.EXCEL_UPLOAD_ERROR_NULL);
        }
        //执行请购单下个流程
        Wrapper<PurchaseProcessTaskRes> taskResult = commonService.executeRequisitionProcess(requisition, PurchaseConstants.DIRECT_EXEC_TASK);
        if (taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }
        //保存修改的请购单
        purchaseRequisitionRepository.save(requisition);
        //内部流转记录
        commonService.savePurchaseInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), req.getId(), RequisitionOperationEnum.VALIDATE_GRADE_TWO.getName(), RequisitionInnerStatusEnum.getNameByCode(requisition.getBuyerInnerStatus()), "");
        return Wrapper.success();
    }

    /**
     * 查询请购单内部状态枚举值
     * @return 查询结果
     */
    @Override
    public Wrapper<List<RequisitionInnerStatusEnumRes>> findInnerStatusEnum() {
        return Wrapper.success(Arrays.stream(RequisitionInnerStatusEnum.values()).map(value -> new RequisitionInnerStatusEnumRes(value.getCode(), value.getName())).collect(Collectors.toList()));
    }

    /**
     * 待请购单转采购订单-分页查询
     * @param loginUser 登录用户信息
     * @param req       接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<RequisitionPageRes>> getTransferPurchasePage(UserLoginCacheDTO loginUser, RequisitionPageReq req) {
        return commonService.getBaseRequisitionPage(loginUser, req, null, true);
    }

    /**
     * 转采购订单-查看详情
     * @param loginUser 登录用户信息
     * @param req       接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<TransferPurchaseDetailRes> getTransferPurchaseDetail(UserLoginCacheDTO loginUser, CommonIdRequest req) {
        PurchaseRequisition requisition = purchaseRequisitionRepository.findById(req.getId()).orElse(null);
        if (requisition == null) {
            return Wrapper.fail(ResponseCode.EXCEL_UPLOAD_ERROR_NULL);
        }
        if (!requisition.getBuyerMemberId().equals(loginUser.getMemberId()) || !requisition.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_WRONG_ROLE);
        }

        TransferPurchaseDetailRes detailRes = new TransferPurchaseDetailRes();
        //基本信息
        detailRes.setRequisitionId(requisition.getId());
        detailRes.setRequisitionNo(requisition.getRequisitionNo());
        detailRes.setDigest(requisition.getDigest());
        detailRes.setDeliverTime(requisition.getDeliverTime() == null ? "" : requisition.getDeliverTime().format(PurchaseConstants.DEFAULT_DATE_FORMATTER));
        detailRes.setDepartmentId(requisition.getDepartmentId());
        detailRes.setDepartment(requisition.getDepartment());
        detailRes.setPurpose(requisition.getPurpose());
        detailRes.setVendorMemberId(requisition.getVendorMemberId());
        detailRes.setVendorRoleId(requisition.getVendorRoleId());
        detailRes.setVendorMemberName(requisition.getVendorMemberName());
        detailRes.setCreator(requisition.getCreator());
        detailRes.setCreateTime(requisition.getCreateTime().format(PurchaseConstants.DEFAULT_TIME_FORMATTER));
        BeanUtils.copyProperties(requisition, detailRes);
        //订单商品汇总信息
        PurchaseProductRes productRes = commonService.purchaseProducts(requisition);
        detailRes.setProduct(productRes.getProductVO());
        return Wrapper.success(detailRes);
    }

    /**
     * 新增请购单订单-选择采购物料列表
     * @param loginUser 登录用户信息
     * @param req       接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MaterialPageRes>> getOrderPurchaseMaterialPage(UserLoginCacheDTO loginUser, MaterialPageReq req) {
        //表实体
        QPurchaseRequisition qRequisition = QPurchaseRequisition.purchaseRequisition;
        QPurchaseProduct qPurchaseProduct = QPurchaseProduct.purchaseProduct;
        //构造查询条件
        BooleanBuilder predicates = new BooleanBuilder();

        predicates.and(qRequisition.id.eq(req.getRequisitionId()));
        predicates.and(qRequisition.buyerMemberId.eq(loginUser.getMemberId()));
        predicates.and(qRequisition.buyerRoleId.eq(loginUser.getMemberRoleId()));
        predicates.and(qPurchaseProduct.quantity.gt(qPurchaseProduct.transferQuantity));
        if (StrUtil.isNotBlank(req.getProductNo())) {
            predicates.and(qPurchaseProduct.productNo.like("%" + req.getProductNo() + "%"));
        }
        if (StrUtil.isNotBlank(req.getName())) {
            predicates.and(qPurchaseProduct.name.like("%" + req.getName() + "%"));
        }
        if (StrUtil.isNotBlank(req.getSpec())) {
            predicates.and(qPurchaseProduct.spec.like("%" + req.getSpec() + "%"));
        }

        JPAQuery<PurchaseProduct> query = jpaQueryFactory.select(qPurchaseProduct).from(qRequisition).join(qPurchaseProduct).on(qRequisition.id.eq(qPurchaseProduct.purchaseRequisition.id)).where(predicates);

        long totalCount = query.fetchCount();

        List<MaterialPageRes> pageRes = query.offset(req.getCurrentOffset()).limit(req.getPageSize()).fetch().stream().map(MaterialPageRes::new).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(totalCount, pageRes));
    }

    @Override
    public Wrapper<PurchaseDeliveryTypeItemRes> getDeliveryMethodItems(HttpHeaders headers) {
        PurchaseDeliveryTypeItemRes itemVO = new PurchaseDeliveryTypeItemRes();
        itemVO.setDeliveryMethods(Arrays.stream(DeliveryMethodEnum.values()).map(e -> new DeliveryMethodRes(e.getCode(), e.getMsg())).sorted(Comparator.comparingInt(DeliveryMethodRes::getDeliveryMethod)).collect(Collectors.toList()));
        itemVO.setDeliveryTypes(Arrays.stream(DeliveryTypeEnum.values()).map(e -> new DeliveryTypeRes(e.getCode(), e.getMsg())).sorted(Comparator.comparingInt(DeliveryTypeRes::getDeliveryType)).collect(Collectors.toList()));
        return Wrapper.success(itemVO);
    }
}
